import uuid
import threading
import time
from typing import Any

from app import config
from model import model
from bidict import bidict


class MQTTServer:
    def __init__(self):

        self.pending_acks = {}
        self.device_msg = {}
        self.lock = threading.Lock()

    def deal_message(self, msg):
        """ 存消息 """
        with self.lock:
            self.device_msg[msg.get('topic')] = msg.get('payload')
            if msg.get('payload') == '123':
                self.equip_offline(topic=msg.get('topic'))

            if self.device_msg.get(msg.get('topic'))[:2] == '52':
                self.equip_online(topic=msg.get('topic'), payload=msg.get('payload'))

    def save_ack(self, msg):
        with self.lock:
            self.pending_acks[msg.get('topic')] = msg.get('payload')

    def send_command(self, topic, mqtt_client, command):
        """发送命令到设备并等待ACK"""
        message_id = str(uuid.uuid1())
        publish_result = mqtt_client.publish(topic=topic, payload=command + message_id, qos=0, retain=False)

        # 开始查询ACK消息
        time.sleep(3)
        bi_dict = bidict(self.pending_acks)
        if bi_dict.inverse.get(message_id) is not None:  # 说明这个message_id 已经返回了
            return publish_result

    def equip_offline(self, topic):
        """ 设备离线 """
        with self.lock:
            user = config.DevelopmentConfig.session.query(model.EqInfo).filter_by(mac=topic).first()
            if user is not None:
                user.status = 0
                config.DevelopmentConfig.session.commit()

    def equip_online(self, topic, payload):
        """ 设备上线 """
        with self.lock:
            user = config.DevelopmentConfig.session.query(model.EqInfo).filter_by(mac=topic).first()
            if user is None:
                if len(payload.split("7c")) == 5:
                    data_list = payload.split(
                        "7c")  # ['52', '3839383630344630313132334330393531383336', '34', '66616e', '56303031']
                    current_time = time.time()
                    sim_card_num = data_list[1]
                    product_id = data_list[2]
                    eq_type = data_list[3]
                    version = data_list[4]
                    new_user = model.EqInfo(mac=topic, power_ontime=int(current_time), add_time=int(current_time),
                                            eq_type=eq_type, things_cart_num='', status=1,
                                            sim_card_num=sim_card_num, product_id=product_id, version=version)
                    config.DevelopmentConfig.session.add(new_user)

                    # 提交事务
                    config.DevelopmentConfig.session.commit()
            else:
                # user = config.session.query(model.EqInfo).filter_by(mac=topic).first()
                # if user is not None:
                user.status = 1
                config.DevelopmentConfig.session.commit()

    def equip_temperature(self, topic) -> tuple[Any, Any] | str:
        """ 获取温度 """
        payload = self.device_msg.get(topic)
        if payload is not None:
            # payload = self.redis.get(name=topic).decode()
            if payload[:2] == 'US':
                humidity = payload[payload.find("HA") + 2:payload.find("TA")]
                temperature = payload[payload.find("TA") + 2:]
                return humidity, temperature
            else:
                return "请稍后重试"
        else:
            return "请稍后重试"

if __name__ == '__main__':
    user = config.DevelopmentConfig.session.query(model.EqInfo).filter_by(mac="test").first()
    print(user.status)